<template lang="pug">
.progress(:style="{width:percent+'%', height:height, color:color}")
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

@Component({})
export default class Loading extends Vue {
  public percent: number = 0;
  public show: boolean = false;
  public canSuccess: boolean = true;
  public duration: number = 3000;
  public color: string = "#77b6ff";
  public height: string = "2px";
  public failedColor: string = "red";
  private _timer: NodeJS.Timeout | number | undefined = undefined;
  private _cut: number = 0;

  public start(): Loading {
    this.show = true;
    this.canSuccess = true;
    if (this._timer) {
      clearInterval(this._timer as NodeJS.Timeout);
      this.percent = 0;
    }
    // Math.floor() === 向下取整
    this._cut = 10000 / Math.floor(this.duration);
    this._timer = setInterval(() => {
      this.increase(this._cut * Math.random());
      if (this.percent > 95) {
        this.finish();
      }
    }, 100);
    return this;
  }

  public set(num: number): Loading {
    this.show = true;
    this.canSuccess = true;
    this.percent = Math.floor(num);
    return this;
  }

  public get(): number {
    return Math.floor(this.percent);
  }

  public increase(num: number): Loading {
    this.percent = this.percent + Math.floor(num);
    return this;
  }

  public decrease(num: number): Loading {
    this.percent = this.percent - Math.floor(num);
    return this;
  }

  public finish(): Loading {
    this.percent = 100;
    this.hide();
    return this;
  }
  public pause(): Loading {
    if (this._timer) {
      clearInterval(this._timer as NodeJS.Timeout);
    }
    return this;
  }

  public hide(): Loading {
    if (this._timer) {
      clearInterval(this._timer as NodeJS.Timeout);
    }
    this._timer = undefined;
    setTimeout(() => {
      this.show = false;
      Vue.nextTick(
        (): void => {
          setTimeout((): void => {
            this.percent = 0;
          }, 200);
        }
      );
    }, 500);
    return this;
  }

  public fail(): Loading {
    this.canSuccess = false;
    return this;
  }
}
</script>
